#ifndef KLIPPY_CONFIG_H
#define KLIPPY_CONFIG_H

#include <string>
#include <map>
#include <memory>
#include <functional>
#include <set>
#include "nlohmann/json.hpp"
#include "klippy/logging.h"

namespace klippy {

// 配置项验证规则
struct ConfigValidationRule {
    std::string type;              // 值类型：string, int, float, bool
    bool required = false;         // 是否必需
    std::string default_value;     // 默认值
    std::vector<std::string> enum_values;  // 枚举值列表（如果适用）
    double min_value = 0;          // 最小值（数值类型）
    double max_value = 0;          // 最大值（数值类型）
    std::string regex_pattern;     // 正则表达式模式（字符串类型）
    std::string description;       // 配置项描述
};

// 配置变更事件
struct ConfigChangeEvent {
    std::string key;              // 变更的配置项
    std::string old_value;        // 旧值
    std::string new_value;        // 新值
    std::string change_type;      // 变更类型：add, modify, remove
};

class Config {
public:
    using ConfigChangeCallback = std::function<void(const ConfigChangeEvent&)>;
    
    static std::shared_ptr<Config> load(const std::string& filename);
    
    // 基本获取方法
    std::string get_string(const std::string& key, const std::string& default_val = "") const;
    int get_int(const std::string& key, int default_val = 0) const;
    float get_float(const std::string& key, float default_val = 0.0f) const;
    bool get_bool(const std::string& key, bool default_val = false) const;

    // 设置方法
    void set_string(const std::string& key, const std::string& value);
    void set_int(const std::string& key, int value);
    void set_float(const std::string& key, float value);
    void set_bool(const std::string& key, bool value);

    // 配置验证
    bool validate() const;
    void add_validation_rule(const std::string& key, const ConfigValidationRule& rule);
    std::vector<std::string> get_validation_errors() const;
    
    // 配置保存和加载
    bool save() const;  // 保存到文件
    bool reload();      // 重新加载配置
    bool auto_save();   // 启用自动保存
    
    // 配置项废弃管理
    void mark_deprecated(const std::string& key, const std::string& message = "");
    bool is_deprecated(const std::string& key) const;
    std::map<std::string, std::string> get_deprecated_items() const;
    
    // 配置变更通知
    void add_change_listener(const ConfigChangeCallback& callback);
    void remove_change_listener(const ConfigChangeCallback& callback);
    
    // 配置项元数据
    bool has_key(const std::string& key) const;
    std::vector<std::string> get_keys() const;
    std::string get_description(const std::string& key) const;

private:
    Config() = default;
    
    bool parse_file(const std::string& filename);
    void notify_change(const ConfigChangeEvent& event);
    bool validate_section(const std::string& section) const;
    void load_default_validation_rules();
    
    nlohmann::json config_;
    std::string config_path_;
    Logger& logger_ = Logger::get_instance();
    
    std::map<std::string, ConfigValidationRule> validation_rules_;
    std::set<std::string> deprecated_keys_;
    std::map<std::string, std::string> deprecation_messages_;
    std::vector<ConfigChangeCallback> change_listeners_;
    bool auto_save_enabled_ = false;
    mutable std::vector<std::string> validation_errors_;
};

} // namespace klippy

#endif // KLIPPY_CONFIG_H